/*
 *  world.cpp
 *  
 *
 *  Created by Brian Bilbo on 12/03/09.
 *
 */

#include "world.h"
#define COP_DISTANCE_APART 20
#define HIDEOUT_DISTANCE_APART 50

#include <iostream>
using namespace std;

World::World() {
	/* initialize random seed: */
 	srand ( time(NULL) );
	bool flag1 = true;
	Position* startPos = new Position();
	Position* finPos = new Position();
	
	map = new Map();
	
	apos = genAvailPos();
	
	for (int ii = 0; ii < 3; ii++) {
		Position* temp = genRandomPos();
		printf("Cops start x position %d y position %d\n", temp->posX, temp->posY);
		cops.push_back(new Cop(temp, map));
	}
	
	while(true)
	{
		flag1 = true;
		startPos = genRandomPos();
		
		for (int k = 0; k < cops.size(); k++){
			if ( (abs(startPos->posX - ((cops[k]->myPosition)->posX)) < COP_DISTANCE_APART) || (abs(startPos->posY - ((cops[k]->myPosition)->posY)) < COP_DISTANCE_APART)){
				flag1 = false;
				break;
			}
		}
		
		if(flag1){
			finPos = genRandomPos();
			while(((abs(startPos->posX - finPos->posX)) < HIDEOUT_DISTANCE_APART) || ((abs(startPos->posY - finPos->posY)) < HIDEOUT_DISTANCE_APART))
				finPos = genRandomPos();
			break;
		}
	}
	
	
	printf("Robber start x position %d y position %d\n", startPos->posX, startPos->posY);
	printf("Robber finish x position %d y position %d\n", finPos->posX, finPos->posY);
	
	robber = new Robber(cops, startPos, finPos, map);
	
	for (int ii = 0; ii < 3; ii++) {
		cops[ii]->addRobber(robber);
		cops[ii]->addCops(cops);
		cops[ii]->robberWhereabouts(robber->myPosition, robber->myDirection);
	}
	cout << "\nt = 0\n";
	print();

	
	int jj = 0;
	while (jj < 5) {
		for (int ii = 0; ii < cops.size(); ii++) {
			if (copCaughtRobber(cops[ii])) {
				return;
			}
		}
		
		robber->takeTurn();
		
		for (int ii = 0; ii < cops.size(); ii++) {
			cops[ii]->takeTurn();
		}
		
		cout << "\nt = " << (jj+1) << "\n";
		print();
		
		jj++;
	}
	
}

World::~World() {
	delete map;
	
	delete robber;
	
	for (int ii = 0; ii < cops.size(); ii++) {
		delete cops[ii];
	}
}

bool World::copCaughtRobber( Cop* _cop ) {
	return false;
}

vector<Position*> World::genAvailPos()
{
 vector<Position*> res;
 for(int i = 0; i < map->numberOfRows; i++){
	for (int j = 0; j < map->numberOfCols; j++){
		if((map->nodes[j][i])->checkConnected())
			res.push_back(new Position(j, i));
	}
 }
 return res;
}

Position* World::genRandomPos()
{
	Position* res = new Position();
	Position* temp = new Position();	
	temp = apos[rand() % (apos.size())];
	res->posX = (temp->posX)*10;
	res->posY = (temp->posY)*10;
	return res;
}

void World::print() {
	for (int row = 0; row < Map::numberOfRows; row++) {
		for (int col = 0; col < Map::numberOfCols; col++) {
			bool someoneHere = false;
			if ((robber->myPosition->posX)/10 == col && (robber->myPosition->posY)/10 == row) {
				someoneHere = true;
				cout << "R";
			}
			for (int ii = 0; ii < cops.size(); ii++) {
				Cop* currentCop = cops[ii];
				if ((currentCop->myPosition->posX)/10 == col && (currentCop->myPosition->posY)/10 == row) {
					someoneHere = true;
					cout << "C";
				}
			}
			if (!someoneHere) {
				cout << "*";
			}
			if (col < Map::numberOfCols-1) {
				if ((map->nodes[row][col])->eastEdge != NULL) {
					cout << "-";
				} else {
					cout << " ";
				}
			}
		}
		cout << "\n";
		for (int col = 0; col < Map::numberOfCols; col++) {
			if (row < Map::numberOfRows-1) {
				if ((map->nodes[row][col])->southEdge != NULL) {
					cout << "| ";
				} else {
					cout << "  ";
				}
			}
		}
		cout << "\n";
	}
}